import uiautomation as auto


class Node:
    def __init__(self, element: auto.Control):
        self.name = element.Name
        self.class_name = element.ClassName
        self.type = element.ControlType
        self.valid = True
        self.children = []
    
    def convert_to_dict(self):
        return {
            'name': self.name,
            'children': [child.convert_to_dict() for child in self.children]
        }
    
    # Write the node tree
    def write_node_tree(self, fileHandle, level=0):
        fileHandle.write("  " * level + f'Name: "{self.name}", Type: "{self.type}"\n')
        # print("  " * level + f'Name: "{node.name}"')
        for child in self.children:
            child.write_node_tree(fileHandle, level + 1)
    
    # Summarize the node
    def get_summary_text(self, level=0):
        if self.children == []:
            return "  " * level + f'{self.name}\n'
        else:
            summary = ""
            if self.name != "":
                summary = "  " * level + f'{self.name}\n'
            else:
                # summary = "  " * level + '\n'
                for child in self.children:
                    summary += child.get_summary_text(level + 1)
        return summary
    

# Build the node from the UI element
def build_node(element, max_children=-1):
    node = Node(element)
    
    has_valid_child = False
    added_children = 0
    for child in element.GetChildren():
        if max_children > 0 and added_children >= max_children:
            # print("Max children reached.")
            break
        child_node = build_node(child, max_children)
        # Not accept invalid children
        if child_node.valid:
            node.children.append(child_node)
            added_children += 1
            has_valid_child = True
    
    # Define what is a valid node
    if node.name == "" and not has_valid_child:
        node.valid = False
    # Compresse the node if it has only one child
    if node.name == "" and len(node.children) == 1:
        node = node.children[0]
    
    return node
    